 		 --------------------------------
		  CrackMe [id:9] coded by tC...
		 Tutorial by Lucifer48, 21 mai 99
		 --------------------------------

Protection: Unlock code + Serial/Name
Still delphi for this crackme (324 ko!)

I apolozige for my grammar errors, i'am french.

==============
1. UNLOCK CODE
==============

When the right code is entered, the menu "Register" is enabled.
So, the check procedure is tested after each key pressed.
As usual, a bpx hmemcpy allow us to enter in the code.

XXXX:004442F7  E898F9FDFF     CALL 00423C94
XXXX:004442FC  8B45FC         MOV  EAX,[EBP-04]       ;our unlock-code
XXXX:004442FF  BA88434400     MOV  EDX,00444388       ;oh oh ...
XXXX:00444304  E83BF8FBFF     CALL 00403B44           ;compare CALL
XXXX:00444309  7507           JNZ  00444312           ;if jmp: the code entered is false
XXXX:0044430B  E8BCFFFFFF     CALL 004442CC           ;TO SEE
XXXX:00444310  EB4D           JMP  0044435F           ;jump to end of the routine
XXXX:00444312  833D4C68440002 CMP  DWORD PTR [0044684C],02
XXXX:00444319  7544           JNZ  0044435F           ;jump to end of the routine
XXXX:0044431B   ...
enable the menu Register

-------------------------------------------------------------------------------
XXXX:00444388 43 72 61 63 6B 4D 65 20-5B 69 64 3A 39 5D 20 62  CrackMe [id:9] b
XXXX:00444398 79 20 74 43 2E 2E 2E 20-2E 00 00 00              y tC... ....
-------------------------------------------------------------------------------

Remark: The call 004442CC is only composed by a single instruction:
        MOV DWORD PTR [0044684C],00000002

Ok, to enable the menu Register:
1) We must put the right unlockcode it is:
   CrackMe [id:9] by tC... .
2) Put a BAD unlockcode (because DWORD PTR [0044684C] equal 2) to continue in 0044431B...

So tu summorize: firtly: "CrackMe [id:9] by tC... ." and secondly i press a key (a letter,
a number ...) on my keyboard (not only a Space Sanhedrin ;) ).

The menu is enabled.

======================
2. SERIAL/NAME : INTRO
======================

I enter:
Your Name/ Lucifer48
 Reg. No./ 36157800

The bpx hmemcpy help me again.
Here we are:

XXXX:00444779  E816F5FDFF     CALL 00423C94           ;we exit from here
XXXX:0044477E  8B55F8         MOV  EDX,[EBP-08]       ;serial
XXXX:00444781  B868664400     MOV  EAX,00446868
...
XXXX:00444799  8B45F8         MOV  EAX,[EBP-08]       ;my name
XXXX:0044479C  E893F2FBFF     CALL 00403A34           ;length of the name (result EAX)
XXXX:004447A1  83F805         CMP  EAX,05
XXXX:004447A4  0F88CFB000000  JL   004448A5

We continue (a first loop):

XXXX:004447F6  BB70684400     MOV  EBX,00446870       ;small buffer who receive our serial scrambled
XXXX:004447FB  8D55F8         LEA  EDX,[EBP-08]       ;d *edx : our name
XXXX:004447FE  8B86C8020000   MOV  EAX,[ESI+000002C8]
XXXX:00444804  E88BF4FDFF     CALL 00423C94           ;length of string (in EAX)
XXXX:00444809  8B45F8         MOV  EAX,[EBP-08]       ;my name
XXXX:0044480C  8B55FC         MOV  EDX,[EBP-04]       ;at start [EBP-04]=00000001
XXXX:0044480F  8A4410FF       MOV  AL,[EDX+EAX-01]    ;load the EDX-1 th char
XXXX:00444813  3403           XOR  AL,03
XXXX:00444815  8803           MOV  [EBX],AL           ;save the result
XXXX:00444817  33C0           XOR  EAX,EAX
XXXX:00444819  8A03           MOV  AL,[EBX]
XXXX:0044481B  8B1594684400   MOV  EDX,[00446894]     ;at start [00446894]=00000000
XXXX:00444821  03D2           ADD  EDX,EDX
XXXX:00444823  03C2           ADD  EAX,EDX
XXXX:00444825  A394684400     MOV  [00446894],EAX     ;sauvegarde
XXXX:0044482A  A070684400     MOV  AL,[00446870]
XXXX:0044482F  F62D54684400   IMUL BYTE PTR [00446854] ;in [00446854]: length of name (for me: 9)
XXXX:00444835  0003           ADD  [EBX],AL
XXXX:00444837  33C0           XOR  EAX,EAX
XXXX:00444839  8A03           MOV  AL,[EBX]
XXXX:0044483B  010598684400   ADD  [00446898],EAX     ;a sum...
XXXX:00444841  FF45FC         INC  DWORD PTR [EBP-04] ;next loop
XXXX:00444844  43             INC  EBX                ;next char
XXXX:00444845  4F             DEC  EDI
XXXX:00444846  75B3           JNZ  004447FB           ;loop

What's happen ? (explaination)
For the first char:
00446894: ascii value of 1st char XOR 3 (for me 4C XOR 03 = 4F)
00446898: (ascii value of 1st char XOR 3)*(length of name +1)
          remark: we keep only the 8 bits of low height.
          Example for me: 4F * A = 316 so it's 16 =Z.
Next char:
load the Xth char, X XOR 03 = Y
00446894: Y+2*([00446894])
00446898: Z*(length of name)+Y (we keep 8 bits of low heigh) +[00446898]

Result for me:
-------------------------------------------------------------------------------
XXXX:00446870 16 3C 26 30 2B 2C 37 FD-01                       .<&0+,7..
XXXX:00446880
XXXX:00446890             2D BB 00 00-34 02 00 00                 -...4...
-------------------------------------------------------------------------------

Remark: how we find the value in 00446894 ?
4C XOR 03 = 4F
75 XOR 03 = 76
63 XOR 03 = 60
69 XOR 03 = 6A
66 XOR 03 = 65
65 XOR 03 = 66
72 XOR 03 = 71
34 XOR 03 = 37
38 XOR 03 = 3B

(((((((4F*2 +76)*2 +60)*2 +6A)*2 + 65)*2 +66)*2 +71)*2 +37)*2 + 3B = BB2D (it's ok!!)

We continue just after the loop:

XXXX:00444848  E813FCFFFF     CALL 00444460           ;TO SEE
XXXX:0044484D  E81EFEFFFF     CALL 00444670           ;TO SEE
XXXX:00444852  A150684400     MOV  EAX,[00446850]
XXXX:00444857  3B0554684400   CMP  EAX,[00446854]     ;in [00446854]: length of name (for me: 9)
XXXX:0044485D  7546           JNZ  004448A5

The situation is simple:
If we jump, the serial is bad, otherwise (EAX and [00446854] are equal) so the crackme is
registered, it's done.

Still 2 call to look at; let's go.

==============================
3. SERIAL/NAME : CALL 00444460
==============================

Anather loop:

XXXX:00444492  B870684400     MOV  EAX,00446870       ;our scambled serial
XXXX:00444497  8BCE           MOV  ECX,ESI            ;at start ESI = 00000001
XXXX:00444499  0208           ADD  CL,[EAX]           ; +1 / +2 / +3 / +4 / ...
XXXX:0044449B  80C104         ADD  CL,04              ;+4
XXXX:0044449E  8808           MOV  [EAX],CL
XXXX:004444A0  81E1FF000000   AND  ECX,000000FF
XXXX:004444A6  8B1D90684400   MOV  EBX,[00446890]     ;at start [00446890] = 0
XXXX:004444AC  03DB           ADD  EBX,EBX
XXXX:004444AE  03CB           ADD  ECX,EBX
XXXX:004444B0  890D90684400   MOV  [00446890],ECX
XXXX:004444B6  46             INC  ESI
XXXX:004444B7  40             INC  EAX                ;next char
XXXX:004444B8  4A             DEC  EDX
XXXX:004444B9  75DC           JNZ  00444497           ;loop

Result for me:
-------------------------------------------------------------------------------
XXXX:00446870 1B 42 2D 38 34 36 42 09-0E                       .B-846B..
XXXX:00446880
XXXX:00446890 58 54 00 00                                      XT..
-------------------------------------------------------------------------------

Effectively:
(((((((1B*2 +42)*2 +2D)*2 +38)*2 +34)*2 +36)*2 +42)*2 +09)*2 +0E = 5458 (it's good!!)

XXXX:004444BB  8D4DFC         LEA  ECX,[EBP-04]       ;will save an adress in [EBP-04]
XXXX:004444BE  BA01000000     MOV  EDX,00000001
XXXX:004444C3  A190684400     MOV  EAX,[00446890]     ;for me: EAX=00005458
XXXX:004444C8  E8F731FCFF     CALL 004076C4           ;ascii convertion

This call will convert the value of eax in ascii and the adress of the result is stored in [EBP-04]

XXXX:004444EC  A194684400     MOV  EAX,[00446894]     ;for me: [00446894]=0000BB2D
XXXX:004444F1  030598684400   ADD  EAX,[00446898]     ;for me: [00446898]=00000234
XXXX:004444F7  8B0D90684400   MOV  ECX,[00446890]     ;for me: [00446890]=00005458
XXXX:004444FD  0FAFCE         IMUL ECX,ESI            ;at start ESI = 00000001
XXXX:00444500  2BC1           SUB  EAX,ECX
XXXX:00444502  A39C684400     MOV  [0044689C],EAX
XXXX:00444507  46             INC  ESI
XXXX:00444508  4A             DEC  EDX
XXXX:00444509  75E1           JNZ  004444EC           ;loop
XXXX:0044450B  8D4DFC         LEA  ECX,[EBP-04]       ;will save an adress in [EBP-04]
XXXX:0044450E  BA01000000     MOV  EDX,00000001
XXXX:00444513  A19C684400     MOV  EAX,[0044689C]     ;valeur to convert (*)
XXXX:00444518  E8A731FCFF     CALL 004076C4           ;convert to ascii char

(*) to find this value, it's simple:
[00446894]+[00446898] - [00446890]*(length of name -2)
Example for me:
BB2D+234 - 5458*7 = BD61 - 24E68 = FFFE6EF9

Then this value is converted in ascii char (if for example EAX=3A then we have in memory 38 41)
We can gess that this value will be present is the final serial.

==============================
4. SERIAL/NAME : CALL 00444670
==============================

XXXX:004446A1  A194684400     MOV  EAX,[00446894]     ;for me: [00446894]=0000BB2D
XXXX:004446A6  83C00C         ADD  EAX,0C
XXXX:004446A9  8BD3           MOV  EDX,EBX            ;at start EBX = 00000001
XXXX:004446AB  0FAFD3         IMUL EDX,EBX
XXXX:004446AE  2BC2           SUB  EAX,EDX            ;EAX: value to be converted
XXXX:004446B0  8D55FC         LEA  EDX,[EBP-04]       ;[EBP-04]: futur adress of a part of a serial
XXXX:004446B3  E8DC2FFCFF     CALL 00407694           ;will convert in DECIMAL in ascii (*)
...
(*) we have a first part of a serial

XXXX:004446C6  A198684400     MOV  EAX,[00446898]     ;for me: [00446898]=00000234
XXXX:004446CB  5A             POP  EDX                ;EDX=EBX SHL 05
XXXX:004446CC  2BC2           SUB  EAX,EDX
XXXX:004446CE  03C3           ADD  EAX,EBX            ;add the count of the loop
XXXX:004446D0  8D55F8         LEA  EDX,[EBP-08]       ;[EBP-04]: futur adress of a part of a serial
XXXX:004446D3  E8BC2FFCFF     CALL 00407694           ;DECIMAL convertion into ascii (**)

(**) we have a second part of a serial

XXXX:004446D8  FF75F8         PUSH DWORD PTR [EBP-08] ;part (**)
XXXX:004446DB  6844474400     PUSH 00444744           ;"-"
XXXX:004446E0  FF3560684400   PUSH DWORD PTR [00446860] ;made by call 00444460
XXXX:004446E6  6850474400     PUSH 00444750           ;"H3"
XXXX:004446EB  8BC6           MOV  EAX,ESI            ;d *eax : adress of a final serial
XXXX:004446ED  BA09000000     MOV  EDX,00000009
XXXX:004446F2  E8FDF3FBFF     CALL 00403AF4           ;concat => give a serial final
XXXX:004446F7  43             INC  EBX
XXXX:004446F8  83C604         ADD  ESI,04
XXXX:004446FB  83FB0D         CMP  EBX,0D             ;12 loop
XXXX:004446FE  7591           JNZ  00444691

/* Remarque: small come back:
XXXX:00444691  FF3564684400   PUSH DWORD PTR [00446864] ;made by call 00444460
XXXX:00444697  6838474400     PUSH 00444738             ;"65A"
XXXX:0044469C  6844474400     PUSH 00444744             ;"-"
*/

We are looking for a serial and we have 12 serials! Which is the right one ?

545865A-47928-533-FFFE6EF9H3
545865A-47925-502-FFFE6EF9H3
545865A-47920-471-FFFE6EF9H3
545865A-47913-440-FFFE6EF9H3
545865A-47904-409-FFFE6EF9H3
545865A-47893-378-FFFE6EF9H3         ;These serials are bad!
545865A-47880-347-FFFE6EF9H3
545865A-47865-316-FFFE6EF9H3
545865A-47848-285-FFFE6EF9H3
545865A-47829-254-FFFE6EF9H3
545865A-47808-223-FFFE6EF9H3
545865A-47785-192-FFFE6EF9H3

Remark: we recognize 2 strings (for me 5458 et FFFE6EF9) from the CALL 00444460
        and the 2 strings from the 2 call 00407694.

Last step:
XXXX:00444705  33C0           CALL 0044454C             ;verification (check routine)

==============================
5. SERIAL/NAME : CALL 0044454C
==============================

Remember: to be registered we must have [00446850]=[00446854] (it's the length of the name)

In this call, there are a lot a comparasions, the 12 serials with our onw serial.
(call 00403B44 compare two strings).
As you are a little lost, we will look after a mov instruction which uses the operand
[00446850]. And we find (the call 0044454C isn't very big):

XXXX:004445C2  8B55FC         MOV  EDX,[EBP-04]       ;the TRUE serial
XXXX:004445C5  8B07           MOV  EAX,[EDI]          ;my serial
XXXX:004445C7  E878F5FBFF     CALL 00403B44           ;compare-call
XXXX:004445CC  752A           JNZ  004445F8
XXXX:004445CE  A154684400     MOV  EAX,[00446854]     ;you looked after that!
XXXX:004445D3  A350684400     MOV  [00446850],EAX     ;super!

We see that the true serial is written is memory. For me it is:

5458-47917-564-FFFE6EF9
----
(1)  -----                     (1): see part "3. SERIAL/NAME : CALL 00444460"
      (2)  ---                 (2): (effectively 47917d = BB2Dh) see part "2. SERIAL/NAME : INTRO"
           (3) --------        (3): (effectively 564d = 234h) see part "2. SERIAL/NAME : INTRO"
                 (4)           (4): see part "3. SERIAL/NAME : CALL 00444460"


=============
6. CONCLUSION
=============

Your Name/ Lucifer48
 Reg. No./ 5458-47917-564-FFFE6EF9

	A good crackme by tC, there were a lot of garbage (made by tC and by Delphi), but a simple
D EDX is enough to see the right serial ;)
Good work Cracker!


Lucifer48
(lucifer48@yahoo.com)

PS: Read Sanhedrin's essay, it is different (in my view).
